# Generate $objdir/gcn-device-macros.h from gcn-devices.def
#
# Copyright (C) 2024-2025 Free Software Foundation, Inc.
#
# This file is part of GCC.
#
# GCC is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GCC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3.  If not see
# <http://www.gnu.org/licenses/>.

BEGIN {
  FS= "[(,] *"

  print "/* Generated by gen-gcn-device-macros.awk from gcn-devices.def."
  print "   Do not edit.  */"

  list=""
  generic_list=""
}

/^GCN_DEVICE\(/ {
  gfx=$2
  NAME=$3
  list=(list " OPT_" NAME)

  print ""
  next
}

/XNACK default.*HSACO_ATTR_UNSUPPORTED/ {
  printf "\n#define XNACK_%s \"march=%s:;\"", NAME, gfx
  next
}

/XNACK default.*HSACO_ATTR_OFF/ {
  printf "\n#define XNACK_%s \"march=%s:%{!mxnack*|mxnack=default|mxnack=off:-mattr=-xnack;mxnack=on:-mattr=+xnack};\"", NAME, gfx
  next
}

/XNACK default.*HSACO_ATTR_ANY/ {
  printf "\n#define XNACK_%s \"march=%s:%{mxnack=off:-mattr=-xnack;mxnack=on:-mattr=+xnack};\"", NAME, gfx
  next
}

/XNACK default.*HSACO/ {
  print FILENAME ":" NR ": error: unhandled HSACO default at line (gen-gcn-device-macros.awk)" > "/dev/stderr"
  exit 1
}

/SRAM_ECC default.*HSACO_ATTR_UNSUPPORTED/ {
  printf "\n#define SRAM_%s \"march=%s:;\"", NAME, gfx
  next
}

/SRAM_ECC default.*HSACO_ATTR_ANY/ {
  printf "\n#define SRAM_%s \"march=%s:%{msram-ecc=on:-mattr=+sramecc;msram-ecc=off:-mattr=-sramecc};\"", NAME, gfx
  next
}

/SRAM_ECC default.*HSACO/ {
  print FILENAME ":" NR ": error: unhandled HSACO default at line (gen-gcn-device-macros.awk)" > "/dev/stderr"
  exit 1
}

/WAVE64 mode.*HSACO_ATTR_UNSUPPORTED/ {
  printf "\n#define WAVE64_%s \"march=%s:;\"", NAME, gfx
  next
}

/WAVE64 mode.*HSACO_ATTR_ON/ {
  printf "\n#define WAVE64_%s \"march=%s:-mattr=+wavefrontsize64;\"", NAME, gfx
  next
}

/WAVE64 mode.*HSACO/ {
  print FILENAME ":" NR ": error: unhandled HSACO default at line (gen-gcn-device-macros.awk)" > "/dev/stderr"
  exit 1
}

/CU mode.*HSACO_ATTR_UNSUPPORTED/ {
  printf "\n#define CU_%s \"march=%s:;\"", NAME, gfx
  next
}

/CU mode.*HSACO_ATTR_ON/ {
  printf "\n#define CU_%s \"march=%s:-mattr=+cumode;\"", NAME, gfx
  next
}

/CU mode.*HSACO/ {
  print FILENAME ":" NR ": error: unhandled HSACO default at line (gen-gcn-device-macros.awk)" > "/dev/stderr"
  exit 1
}

/Generic code obj version/ {
  match($0,/Generic code obj version[^\/]*\/[\t ]*([0-9]+)/,m)
  if (m[1] > 0) {
     printf "\n#define GENERIC_%s \"march=%s:--amdhsa-code-object-version=6;\"", NAME, gfx
     generic_list=(generic_list " GENERIC_" NAME)
  }
  next
}

# ABI Version: In principle, the LLVM default would work. However,
# however, when debugging symbols are turned on, mkoffload.cc
# writes a new AMD GPU object file and the ABI version needs to be the
# same. - LLVM <= 17 defaults to 4 while LLVM >= 18 defaults to 5.
# GCC supports LLVM >= 13.0.1 and only LLVM >= 14 supports version 5.
# Code object V6 is supported since LLVM 19.
#
# Keep in sync with 'amdhsa.version' in gcn.cc
#
END {
  print ""
  print ""
  printf "#define ABI_VERSION_OPT \"%%{\"%s \"!march=*|march=*:--amdhsa-code-object-version=4} \"\n", generic_list
  printf "#define XNACKOPT \"%%{\"%s \":%%eexpected march\\n} \"\n", gensub (/OPT/, "XNACK", "g", list)
  printf "#define SRAMOPT \"%%{\"%s \":%%eexpected march\\n} \"\n", gensub (/OPT/, "SRAM", "g", list)
  printf "#define WAVE64OPT \"%%{\"%s \":%%eexpected march\\n} \"\n", gensub (/OPT/, "WAVE64", "g", list)
  printf "#define CUMODEOPT \"%%{\"%s \":%%eexpected march\\n} \"\n", gensub (/OPT/, "CU", "g", list)
}
